package utile

import (
	"etcd/config"
	"fmt"
	"github.com/gomodule/redigo/redis"
	jsoniter "github.com/json-iterator/go"
)

type redigoUtil struct {
	conn redis.Conn
}

var redigo *redigoUtil

func GetRedigo() (redigo *redigoUtil, err error) {
	if redigo != nil {
		return redigo, nil
	}
	config := config.GetConfig()
	redifConfig := config.Data.Redis
	address := fmt.Sprintf("%s:%s", redifConfig.Host, redifConfig.Port)
	conn, err := redis.Dial(redifConfig.Driver, address)
	if err != nil {
		return nil, err
	}
	redigo = &redigoUtil{conn}
	return redigo, nil
}

func (r *redigoUtil) CloseConn() {
	if r.conn != nil {
		_ = r.conn.Close()
	}
}

func (r *redigoUtil) Set(key, value string) error {
	_, err := r.conn.Do("SET", key, value)
	defer r.CloseConn()
	return err
}

func (r *redigoUtil) SetEx(key, value string, expire int) error {
	_, err := r.conn.Do("SET", key, value)
	defer r.CloseConn()
	if err != nil {
		return err
	}
	_, err = r.conn.Do("EXPIRE", key, expire)
	if err != nil {
		return err
	}
	return nil
}

func (r *redigoUtil) SetMap(key, value map[string]interface{}) error {
	json, _ := jsoniter.Marshal(value)
	_, err := r.conn.Do("SET", key, json)
	defer r.CloseConn()
	return err
}

func (r *redigoUtil) Get(key string) (value string, err error) {
	value, err = redis.String(r.conn.Do("GET", key))
	defer r.CloseConn()
	return
}

func (r *redigoUtil) Del(key string) error {
	_, err := r.conn.Do("DEL", key)
	defer r.CloseConn()
	return err
}

func (r *redigoUtil) Lpush(key, value string) error {
	_, err := r.conn.Do("lpush", key, value)
	defer r.CloseConn()
	return err
}

func (r *redigoUtil) Rpush(key, value string) error {
	_, err := r.conn.Do("rpush", key, value)
	defer r.CloseConn()
	return err
}

func (r *redigoUtil) Lpop(key, value string) error {
	_, err := r.conn.Do("lpop", key, value)
	defer r.CloseConn()
	return err
}

func (r *redigoUtil) Rpop(key, value string) error {
	_, err := r.conn.Do("rpop", key, value)
	defer r.CloseConn()
	return err
}
